package main

import (
	"fmt"
	"strings"
)

type SinglyLinkedList struct {
	head *Node
}

func (list *SinglyLinkedList) Append(e interface{}) {
	node := &Node{
		e:    e,
		next: nil,
	}
	head := list.head
	if head == nil {
		list.head = node
	} else {
		next := head
		for {
			if next.next == nil {
				next.next = node
				break
			}
			next = next.next
		}
	}
}

func (list *SinglyLinkedList) Print() {
	next := list.head
	s := "["
	for {
		if next == nil {
			break
		}
		s += fmt.Sprintf("%v, ", next.e)
		next = next.next
	}
	fmt.Println(strings.TrimRight(strings.TrimSpace(s), ",") + "]")
}

func (list *SinglyLinkedList) Peek() (e interface{}) {
	next := list.head
	if next == nil {
		return nil
	}
	return next.e
}

func (list *SinglyLinkedList) Poll() (e interface{}) {
	next := list.head
	if next == nil {
		return nil
	}
	list.head = next.next
	next.next = nil
	return next.e
}

func (list *SinglyLinkedList) Iterate() *SinglyLinkedListIterator {
	return &SinglyLinkedListIterator{
		current: list.head,
	}
}

type Node struct {
	e    interface{}
	next *Node
}

type Iterator interface {
	HasNext() bool
	Next() interface{}
}

type SinglyLinkedListIterator struct {
	current *Node
}

func (iter *SinglyLinkedListIterator) HasNext() bool {
	return iter.current != nil
}

func (iter *SinglyLinkedListIterator) Next() interface{} {
	if iter.current == nil {
		return nil
	}
	e := iter.current.e
	iter.current = iter.current.next
	return e
}

type Student struct {
	id       int
	name     string
	nickname string
}

func (student *Student) String() string {
	return fmt.Sprintf("{id=%d, name=%s, nickname=%s}", student.id, student.name, student.nickname)
}

func main() {

	list := SinglyLinkedList{}

	s1 := &Student{1, "宋江", "及时雨"}
	s2 := &Student{2, "卢俊义", "玉麒麟"}

	// 追加
	list.Append(s1)
	list.Append(s2)

	// 遍历打印
	list.Print()

	// 获取第一个元素，但是不移除
	e := list.Peek().(*Student)
	fmt.Printf("%d %s %s\n", e.id, e.name, e.nickname)

	// 迭代
	iterate := list.Iterate()
	for {
		hasNext := iterate.HasNext()
		if !hasNext {
			break
		}

		next := iterate.Next()
		stu := next.(*Student)
		fmt.Printf("迭代 - %d %s %s\n", stu.id, stu.name, stu.nickname)
	}

	fmt.Printf("Iterator is %p, HasNext is %v\n", iterate, iterate.HasNext())
	fmt.Printf("Iterator is %p, Next is %v\n", iterate, iterate.Next())
	fmt.Printf("Iterator is %p, Next is %v\n", iterate, iterate.Next())

	// 获取元素
	for {
		e1 := list.Poll()
		if e1 == nil {
			break
		}
		stu := e1.(*Student)
		fmt.Printf("%d %s %s\n", stu.id, stu.name, stu.nickname)
	}

	// 遍历打印
	list.Print()

	// 迭代
	iterate = list.Iterate()

	fmt.Printf("Iterator is %p, HasNext is %v\n", iterate, iterate.HasNext())
	fmt.Printf("Iterator is %p, Next is %v\n", iterate, iterate.Next())
	fmt.Printf("Iterator is %p, Next is %v\n", iterate, iterate.Next())
	for {
		hasNext := iterate.HasNext()
		if !hasNext {
			break
		}
		next := iterate.Next()
		stu := next.(*Student)
		fmt.Printf("%d %s %s\n", stu.id, stu.name, stu.nickname)
	}
}
